Set up libraries

Load data

c14dates <- read_csv("c14dates.csv")
Rows: 1452 Columns: 16── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (10): industry, site, unit, calib.curve, sample.id, material, delta 13, method&id, comments, citation
dbl  (6): ID, Use, BP.cal.median, C14.mean, C14.SD, C14.COV
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Figure 1: Journal Publications

rr.papers %>% 
  ggplot(aes(x=years)) + 
  geom_path(aes(y=JAS.risk/JAS.papers, color='Journal of Archaeological Science', lty='risk'), group=1, lwd=1.5) + 
  geom_path(aes(y=JAS.resilience/JAS.papers, color='Journal of Archaeological Science', lty='resilience'), group=1, lwd=1.5) + 
  geom_path(aes(y=Antiquity.risk/Antiquity.papers, color='Antiquity', lty='risk'), group=1, lwd=1.5) + 
  geom_path(aes(y=Antiquity.resilience/Antiquity.papers, color='Antiquity', lty='resilience'), group=1, lwd=1.5) + 
  scale_y_continuous(labels = scales::percent) + 
  scale_color_manual(values = c('Journal of Archaeological Science' = 'red', 'Antiquity' = 'blue')) + 
  scale_linetype_manual(values = c('risk' = 'solid', 'resilience' = 'dashed')) + 
  labs(title = "Papers Mentioning Risk or Resilience", 
       subtitle = "Change in Past 40 Years", 
       x="5-year intervals", 
       y="% of papers published", 
       color='journal:', 
       linetype='topic:') + 
  theme_bw(base_size = 30) + 
  theme(legend.position = 'bottom', legend.key.width =  unit(50, "points"))

Modeling Biocultural Interaction

Figure 2: NGRIP2 and GISP2 entire cores

icecores %>%
  ggplot() + 
  geom_line(aes(x=years.BP, y=d18O.GISP2.ppt), color='red', lwd=0.3) + 
  geom_line(aes(x=years.BP, y=d18O.NGRIP2.ppt), color='blue', lwd=0.3) + 
#  geom_smooth(aes(x=years.BP, y=d18O.NGRIP2.ppt, color='ngrip2', lty='ngrip2'), method='loess', span=.07, se=FALSE, lwd = 1.5)  + 
  scale_x_reverse() + 
  geom_vline(xintercept = c(119000, 11650), color = "grey", lwd = 1.5) + 
  #scale_x_continuous(breaks=c(19000,14000,10000), labels = c("19000","14000","10000"), trans = "reverse") + 
  #geom_vline(xintercept = c(19000,14000,10000), lty='dashed', lwd=0.3) + 
  labs(x="years cal BP", 
       y="delta O18\ncolder << — >> warmer", 
       title="NGRIP2 (blue) & GISP2 (red) Greenland Ice Cores") +
  theme_bw(base_size = 24)

Figure 3: Box Plots with Condensed Fitness Categories

Hominin_demography %>% 
  mutate(fitness.aggregated = Fitness, 
         fitness.aggregated = recode(fitness.aggregated, 
                                     "birthrate=deathrate"="equal fitness", 
                                     "birthrate>deathrate"="equal fitness", 
                                     "MM higher mortality"="MM less fit", 
                                     "MM lower fertility"="MM less fit", 
                                     "MM lower mortality"="MM more fit", 
                                     "MN higher mortality"="MN less fit", 
                                     "MN lower fertility"="MN less fit", 
                                     "MN lower mortality"="MN more fit", 
                                     "NN higher mortality"="NN less fit", 
                                     "NN lower fertility"="NN less fit", 
                                     "NN lower mortality"="NN more fit"),
         fitness.aggregated = factor(fitness.aggregated, 
                                     levels = c(
                                       "equal fitness", 
                                       "MM less fit", 
                                       "MM more fit", 
                                       "MN less fit", 
                                       "MN more fit", 
                                       "NN less fit", 
                                       "NN more fit"))) %>% 
  ggplot(aes(x=phenotype, y=population)) + 
  geom_boxplot(fill="grey") + 
  facet_grid(fitness.aggregated~factor(home.range.radius), scales="free_y") + 
  labs(x="agent phenotype", y="population at end of simulation") + 
  theme_bw(base_size = 16)

Figure 4: Example Model Trajectory with Logistical Foraging (Foraging Radius=12)

Hominin_demography_trajectory %>% 
  ggplot(aes(y=population, x=step)) + 
  geom_line(aes(color=phenotype), size=2) +
  scale_color_manual(values = c("red", "orange", "grey", "green", "blue")) + 
  labs(x="model step", y="population", color="agent phenotype") + 
  theme_bw(base_size = 16) + 
  theme(legend.position="bottom")
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
Please use `linewidth` instead.

Demographic Dynamics of West Mediterranean

Figure 5a: NGRIP and GISP for LGM to Holocene

icecores %>% dplyr::filter(years.BP<=35000 & years.BP>=8000) %>% 
  ggplot() + 
  geom_line(aes(x=years.BP, y=d18O.GISP2.ppt), color='red', lwd=.2, alpha=.5) + 
  geom_line(aes(x=years.BP, y=d18O.NGRIP2.ppt), color='blue', lwd=.2, alpha=.5) + 
  geom_smooth(aes(x=years.BP, y=d18O.GISP2.ppt, color='gisp2', lty='gisp2'), method='loess', span=.07, se=FALSE, lwd = 1) + 
  geom_smooth(aes(x=years.BP, y=d18O.NGRIP2.ppt, color='ngrip2', lty='ngrip2'), method='loess', span=.07, se=FALSE, lwd = 1)  + 
  scale_colour_manual(name=NULL, values =c('gisp2'='red','ngrip2'='blue'), labels = c('GISP2','NGRIP2')) + 
  scale_linetype_manual(name=NULL, values =c('gisp2'='solid','ngrip2'='solid'), labels = c('GISP2','NGRIP2')) + 
  scale_x_reverse() + 
  #scale_x_continuous(breaks=c(19000,14000,10000), labels = c("19000","14000","10000"), trans = "reverse") + 
  #geom_vline(xintercept = c(19000,14000,10000), lty='dashed', lwd=0.3) + 
  labs(x="years cal BP", 
       y="delta O18\ncolder << — >> warmer", 
       color="Cores",
       title="Paleoclimate Proxies from Greenland Ice Cores") +
  theme_minimal(base_size = 18) + 
  theme(legend.position=c(.95,.15), 
        plot.title = element_text(face = "bold", hjust = 0.5), 
        #axis.text.y = element_text(hjust = -5),
        #panel.grid.major.y = element_blank(),
        #plot.margin = margin(l=30, r=20, t=20, b=20)
        )

Figure 5b: Summed Probability Distribution (SPD) of Radiocarbon Dates in the West Mediterranean

Calibrate dates

c14dates$BP.cal.median <- c14dates %>% 
  with(., calibrate(x=C14.mean, errors=C14.SD, calCurves = calib.curve, normalised=TRUE, calMatrix=FALSE)) %>% 
  medCal()

Calculate SPD

date.bins <- c14dates %>% 
  dplyr::filter(calib.curve != "normal") %>%  
  with(., binPrep(site, C14.mean, 100))

model.all <- c14dates %>% 
  dplyr::filter(calib.curve != "normal") %>%  
  with(., calibrate(x=C14.mean, errors=C14.SD, calCurves = calib.curve, normalised=TRUE, calMatrix=FALSE)) %>% 
  modelTest(., 
            errors = c14dates$C14.SD, 
            timeRange = c(38000,5000), 
            runm = 500, 
            model="exponential", 
            datenormalised=TRUE, 
            nsim = 200, 
            ncores = ncores,
            method = 'calsample', 
            bins = date.bins)

Graph SPD

par(mar=c(7,10,7,3))
plot(model.all, xlim = c(35000,8000), col.obs = 'red', lwd.obs = 3, drawaxes = F)
axis(1, cex.axis = 1, pos = -.0006)
axis(2, cex.axis = 1, pos = 35500)
mtext(side=1, line=3, "years cal BP", cex=1.3)
mtext(side=2, line=4, "summed probability", cex=1.3)
title(main=paste("West Mediterranean Late Pleistocene Assemblages (N = ", nrow(subset(c14dates, calib.curve != "normal")), ")"), cex.main = 1.5)

Figure 5c: SPDs of Aggregated Technocomplexes

Classify aggregated technocomplexes

c14dates <- c14dates %>% 
  mutate(industry.group = 
           case_when(
             str_detect(tolower(industry), "aurig") ~ "Aurignacian", 
             str_detect(tolower(industry), "gdrav") ~ "Gravettian",  
             str_detect(tolower(industry), "solut") ~ "Solutrean",
             str_detect(tolower(industry), "middle solutrean") ~ "Solutrean", 
             str_detect(tolower(industry), "salp") ~ "Solutrean",              
             str_detect(tolower(industry), "epig") ~ "Magdalenian",  
             str_detect(tolower(industry), "epi-gr") ~ "Magdalenian",
             str_detect(tolower(industry), "eppig") ~ "Magdalenian",
             str_detect(tolower(industry), "eppgr") ~ "Magdalenian",
             str_detect(tolower(industry), "apig") ~ "Magdalenian",
             str_detect(tolower(industry), "magd") ~ "Magdalenian",
             str_detect(tolower(industry), "badeg") ~ "Magdalenian",
             str_detect(tolower(industry), "gravet") ~ "Gravettian",  
             str_detect(tolower(industry), "gravt") ~ "Gravettian",  
             str_detect(tolower(industry), "azil") ~ "Epipaleolithic", 
             str_detect(tolower(industry), "romanell") ~ "Epipaleolithic", 
             str_detect(tolower(industry), "epipal") ~ "Epipaleolithic", 
             str_detect(tolower(industry), "mesol") ~ "Mesolithic", 
             str_detect(tolower(industry), "sauve") ~ "Mesolithic", 
             str_detect(tolower(industry), "tarden") ~ "Mesolithic", 
             str_detect(tolower(industry), "montcl") ~ "Mesolithic", 
             str_detect(tolower(industry), "montad") ~ "Mesolithic", 
             str_detect(tolower(industry), "castel") ~ "Mesolithic"
             ), 
         industry.group = factor(industry.group, 
                                 levels = c("Aurignacian", 
                                            "Gravettian", 
                                            "Solutrean", 
                                            "Magdalenian", 
                                            "Epipaleolithic", 
                                            "Mesolithic")),
         .after=industry)

Calculate SPDs of aggregated technocomplexes

c14dates.industry.group <- c14dates %>% 
  dplyr::filter(!is.na(industry.group) & calib.curve != "normal")

c14dates.industry.group <- c14dates.industry.group[order(c14dates.industry.group$industry.group), ]

date.bins <-  c14dates.industry.group %>% 
  with(., binPrep(site, C14.mean, 100))

stacked.spd <- c14dates.industry.group %>% 
  with(., calibrate(x=C14.mean, errors=C14.SD, calCurves = calib.curve, normalised=TRUE, calMatrix=FALSE)) %>% 
  stackspd(timeRange=c(35000,8000), 
           bins=date.bins,
           group=c14dates.industry.group$industry.group, 
           runm = 500, 
           datenormalised=TRUE)

Graph SPDs

par(mar=c(7,10,7,3))
options(digits = 7)
plot(stacked.spd, 
     xlim = c(35000,8000), 
     rescale = T, 
     spdnormalised = F, 
     type = "multipanel", 
     lwd.obs = .5, 
     runm = NA, 
     cex.lab = 1.3, 
     cex.axis = 1, 
     ylab = "summed probability\n", 
     xlab = "years cal BP",
     ymargin = 1, 
     gapFactor = .4, 
     legend.arg=list("topleft", bty = "n", horiz = T, cex = 1))
#axis(1, cex.axis = 2, pos = -.0006)
#axis(2, cex.axis = 2, pos = 35500)
#mtext(side=1, line=5, "years cal BP", cex=2.5)
#mtext(side=2, line=6, "summed probability", cex=2.5)
title(main=paste("West Mediterranean Late Pleistocene Technocomplexes (N = ", nrow(c14dates.industry.group), ")"), cex.main = 1.5)

LS0tCnRpdGxlOiAiUmlzayBhbmQgUmVzaWxpZW5jZSBpbiBEZWVwIFRpbWUiCnN1YnRpdGxlOiAiQW5hbHlzaXMgU2NyaXB0cyBmb3IgUGFwZXIgUHVibGlzaGVkIGluIF9Ib2xvY2VuZV8iCmF1dGhvcjogIkMgTWljaGFlbCBCYXJ0b24sIEFyaXpvbmEgU3RhdGUgVW5pdmVyc2l0eSIKZGF0ZTogIjIwMjMtMDMtMjciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClNldCB1cCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0UsIGVjaG89VH0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShyY2FyYm9uKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShwYXJhbGxlbCkKCm5jb3JlcyA8LSBkZXRlY3RDb3JlcygpCm9wdGlvbnMoTmNwdXMgPSBuY29yZXMpCmBgYAoKCkxvYWQgZGF0YQpgYGB7ciBsb2FkIGRhdGEsIGVjaG89VH0KYzE0ZGF0ZXMgPC0gcmVhZF9jc3YoImMxNGRhdGVzLmNzdiIpCgpIb21pbmluX2RlbW9ncmFwaHkgPC0gcmVhZF9jc3YoIkhvbWluaW5fZGVtb2dyYXBoeS5jc3YiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGNvbHMoLi4uMSA9IGNvbF9pbnRlZ2VyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob21lLnJhbmdlLnJhZGl1cyA9IGNvbF9pbnRlZ2VyKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uID0gY29sX2ludGVnZXIoKSkpCkhvbWluaW5fZGVtb2dyYXBoeSA8LSBIb21pbmluX2RlbW9ncmFwaHkgJT4lIAogIG11dGF0ZShwaGVub3R5cGUgPSByZWNvZGUocGhlbm90eXBlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxIE1NIj0iTU0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyIE0tdHlwZSI9Ik0tdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIjMgaHlicmlkIj0iTU4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0IE4tdHlwZSI9Ik4tdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUgTk4iPSJOTiIpLCAKICAgICAgICAgRml0bmVzcyA9IHJlY29kZShGaXRuZXNzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiaHlicmlkIGhpZ2hlciBtb3J0YWxpdHkiPSJNTiBoaWdoZXIgbW9ydGFsaXR5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgImh5YnJpZCBsb3dlciBmZXJ0aWxpdHkiPSJNTiBsb3dlciBmZXJ0aWxpdHkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAiaHlicmlkIGxvd2VyIG1vcnRhbGl0eSI9Ik1OIGxvd2VyIG1vcnRhbGl0eSIpKSAlPiUgCiAgbXV0YXRlKHBoZW5vdHlwZSA9IGZhY3RvcihwaGVub3R5cGUsIGxldmVscyA9IGMoIk1NIiwgIk0tdHlwZSIsICJNTiIsICJOLXR5cGUiLCAiTk4iKSkpCgpIb21pbmluX2RlbW9ncmFwaHlfdHJhamVjdG9yeSA8LSByZWFkX2NzdigiSG9taW5pbl9kZW1vZ3JhcGh5X3RyYWplY3Rvcmllcy5jc3YiKQpIb21pbmluX2RlbW9ncmFwaHlfdHJhamVjdG9yeSA8LSBIb21pbmluX2RlbW9ncmFwaHlfdHJhamVjdG9yeSAlPiUgCiAgc2VsZWN0KE0udHlwZS54LCBlbmRzX3dpdGgoIi55IikpICU+JSAKICByZW5hbWUoc3RlcCA9IE0udHlwZS54LCAKICAgICAgICAgIk0tVHlwZSIgPSBNLnR5cGUueSwgCiAgICAgICAgICJOLVR5cGUiID0gTi50eXBlLnksIAogICAgICAgICBNTiA9IGh5YnJpZC55LAogICAgICAgICBNTSA9IE1NLnksIAogICAgICAgICBOTiA9IE5OLnkpICU+JSAKICBwaXZvdF9sb25nZXIoMjo2LCBuYW1lc190byA9ICJwaGVub3R5cGUiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpICU+JSAKICBtdXRhdGUocGhlbm90eXBlID0gZmFjdG9yKHBoZW5vdHlwZSwgbGV2ZWxzID0gYygiTU0iLCAiTS1UeXBlIiwgIk1OIiwgIk4tVHlwZSIsICJOTiIpKSkKCmljZWNvcmVzIDwtIHJlYWRfY3N2KCJpY2Vjb3Jlcy5jc3YiKQoKcnIucGFwZXJzIDwtIHJlYWRfY3N2KCJycl9wYXBlcnMuY3N2IikKCmBgYAoKIyMjIEZpZ3VyZSAxOiBKb3VybmFsIFB1YmxpY2F0aW9ucwoKYGBge3IgYmlibGlvbWV0cmljcywgZWNobz1ULCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KcnIucGFwZXJzICU+JSAKICBnZ3Bsb3QoYWVzKHg9eWVhcnMpKSArIAogIGdlb21fcGF0aChhZXMoeT1KQVMucmlzay9KQVMucGFwZXJzLCBjb2xvcj0nSm91cm5hbCBvZiBBcmNoYWVvbG9naWNhbCBTY2llbmNlJywgbHR5PSdyaXNrJyksIGdyb3VwPTEsIGx3ZD0xLjUpICsgCiAgZ2VvbV9wYXRoKGFlcyh5PUpBUy5yZXNpbGllbmNlL0pBUy5wYXBlcnMsIGNvbG9yPSdKb3VybmFsIG9mIEFyY2hhZW9sb2dpY2FsIFNjaWVuY2UnLCBsdHk9J3Jlc2lsaWVuY2UnKSwgZ3JvdXA9MSwgbHdkPTEuNSkgKyAKICBnZW9tX3BhdGgoYWVzKHk9QW50aXF1aXR5LnJpc2svQW50aXF1aXR5LnBhcGVycywgY29sb3I9J0FudGlxdWl0eScsIGx0eT0ncmlzaycpLCBncm91cD0xLCBsd2Q9MS41KSArIAogIGdlb21fcGF0aChhZXMoeT1BbnRpcXVpdHkucmVzaWxpZW5jZS9BbnRpcXVpdHkucGFwZXJzLCBjb2xvcj0nQW50aXF1aXR5JywgbHR5PSdyZXNpbGllbmNlJyksIGdyb3VwPTEsIGx3ZD0xLjUpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygnSm91cm5hbCBvZiBBcmNoYWVvbG9naWNhbCBTY2llbmNlJyA9ICdyZWQnLCAnQW50aXF1aXR5JyA9ICdibHVlJykpICsgCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcyA9IGMoJ3Jpc2snID0gJ3NvbGlkJywgJ3Jlc2lsaWVuY2UnID0gJ2Rhc2hlZCcpKSArIAogIGxhYnModGl0bGUgPSAiUGFwZXJzIE1lbnRpb25pbmcgUmlzayBvciBSZXNpbGllbmNlIiwgCiAgICAgICBzdWJ0aXRsZSA9ICJDaGFuZ2UgaW4gUGFzdCA0MCBZZWFycyIsIAogICAgICAgeD0iNS15ZWFyIGludGVydmFscyIsIAogICAgICAgeT0iJSBvZiBwYXBlcnMgcHVibGlzaGVkIiwgCiAgICAgICBjb2xvcj0nam91cm5hbDonLCAKICAgICAgIGxpbmV0eXBlPSd0b3BpYzonKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDMwKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nLCBsZWdlbmQua2V5LndpZHRoID0gIHVuaXQoNTAsICJwb2ludHMiKSkKYGBgCgoKIyMgTW9kZWxpbmcgQmlvY3VsdHVyYWwgSW50ZXJhY3Rpb24KCiMjIyBGaWd1cmUgMjogTkdSSVAyIGFuZCBHSVNQMiBlbnRpcmUgY29yZXMKCmBgYHtyIE5HUklQMiZHSVNQMiwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9M30KaWNlY29yZXMgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHg9eWVhcnMuQlAsIHk9ZDE4Ty5HSVNQMi5wcHQpLCBjb2xvcj0ncmVkJywgbHdkPTAuMykgKyAKICBnZW9tX2xpbmUoYWVzKHg9eWVhcnMuQlAsIHk9ZDE4Ty5OR1JJUDIucHB0KSwgY29sb3I9J2JsdWUnLCBsd2Q9MC4zKSArIAojICBnZW9tX3Ntb290aChhZXMoeD15ZWFycy5CUCwgeT1kMThPLk5HUklQMi5wcHQsIGNvbG9yPSduZ3JpcDInLCBsdHk9J25ncmlwMicpLCBtZXRob2Q9J2xvZXNzJywgc3Bhbj0uMDcsIHNlPUZBTFNFLCBsd2QgPSAxLjUpICArIAogIHNjYWxlX3hfcmV2ZXJzZSgpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYygxMTkwMDAsIDExNjUwKSwgY29sb3IgPSAiZ3JleSIsIGx3ZCA9IDEuNSkgKyAKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1jKDE5MDAwLDE0MDAwLDEwMDAwKSwgbGFiZWxzID0gYygiMTkwMDAiLCIxNDAwMCIsIjEwMDAwIiksIHRyYW5zID0gInJldmVyc2UiKSArIAogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKDE5MDAwLDE0MDAwLDEwMDAwKSwgbHR5PSdkYXNoZWQnLCBsd2Q9MC4zKSArIAogIGxhYnMoeD0ieWVhcnMgY2FsIEJQIiwgCiAgICAgICB5PSJkZWx0YSBPMThcbmNvbGRlciA8PCDigJQgPj4gd2FybWVyIiwgCiAgICAgICB0aXRsZT0iTkdSSVAyIChibHVlKSAmIEdJU1AyIChyZWQpIEdyZWVubGFuZCBJY2UgQ29yZXMiKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjQpCmBgYAoKIyMjIEZpZ3VyZSAzOiBCb3ggUGxvdHMgd2l0aCBDb25kZW5zZWQgRml0bmVzcyBDYXRlZ29yaWVzCgpgYGB7ciBlY2hvPVQsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KSG9taW5pbl9kZW1vZ3JhcGh5ICU+JSAKICBtdXRhdGUoZml0bmVzcy5hZ2dyZWdhdGVkID0gRml0bmVzcywgCiAgICAgICAgIGZpdG5lc3MuYWdncmVnYXRlZCA9IHJlY29kZShmaXRuZXNzLmFnZ3JlZ2F0ZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJpcnRocmF0ZT1kZWF0aHJhdGUiPSJlcXVhbCBmaXRuZXNzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmlydGhyYXRlPmRlYXRocmF0ZSI9ImVxdWFsIGZpdG5lc3MiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNTSBoaWdoZXIgbW9ydGFsaXR5Ij0iTU0gbGVzcyBmaXQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNTSBsb3dlciBmZXJ0aWxpdHkiPSJNTSBsZXNzIGZpdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1NIGxvd2VyIG1vcnRhbGl0eSI9Ik1NIG1vcmUgZml0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTU4gaGlnaGVyIG1vcnRhbGl0eSI9Ik1OIGxlc3MgZml0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTU4gbG93ZXIgZmVydGlsaXR5Ij0iTU4gbGVzcyBmaXQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNTiBsb3dlciBtb3J0YWxpdHkiPSJNTiBtb3JlIGZpdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5OIGhpZ2hlciBtb3J0YWxpdHkiPSJOTiBsZXNzIGZpdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5OIGxvd2VyIGZlcnRpbGl0eSI9Ik5OIGxlc3MgZml0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTk4gbG93ZXIgbW9ydGFsaXR5Ij0iTk4gbW9yZSBmaXQiKSwKICAgICAgICAgZml0bmVzcy5hZ2dyZWdhdGVkID0gZmFjdG9yKGZpdG5lc3MuYWdncmVnYXRlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXF1YWwgZml0bmVzcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTU0gbGVzcyBmaXQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1NIG1vcmUgZml0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNTiBsZXNzIGZpdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTU4gbW9yZSBmaXQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5OIGxlc3MgZml0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOTiBtb3JlIGZpdCIpKSkgJT4lIAogIGdncGxvdChhZXMoeD1waGVub3R5cGUsIHk9cG9wdWxhdGlvbikpICsgCiAgZ2VvbV9ib3hwbG90KGZpbGw9ImdyZXkiKSArIAogIGZhY2V0X2dyaWQoZml0bmVzcy5hZ2dyZWdhdGVkfmZhY3Rvcihob21lLnJhbmdlLnJhZGl1cyksIHNjYWxlcz0iZnJlZV95IikgKyAKICBsYWJzKHg9ImFnZW50IHBoZW5vdHlwZSIsIHk9InBvcHVsYXRpb24gYXQgZW5kIG9mIHNpbXVsYXRpb24iKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE2KQpgYGAKCiMjIyBGaWd1cmUgNDogRXhhbXBsZSBNb2RlbCBUcmFqZWN0b3J5IHdpdGggTG9naXN0aWNhbCBGb3JhZ2luZyAoRm9yYWdpbmcgUmFkaXVzPTEyKQoKYGBge3IgZWNobz1ULCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KSG9taW5pbl9kZW1vZ3JhcGh5X3RyYWplY3RvcnkgJT4lIAogIGdncGxvdChhZXMoeT1wb3B1bGF0aW9uLCB4PXN0ZXApKSArIAogIGdlb21fbGluZShhZXMoY29sb3I9cGhlbm90eXBlKSwgc2l6ZT0yKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsICJvcmFuZ2UiLCAiZ3JleSIsICJncmVlbiIsICJibHVlIikpICsgCiAgbGFicyh4PSJtb2RlbCBzdGVwIiwgeT0icG9wdWxhdGlvbiIsIGNvbG9yPSJhZ2VudCBwaGVub3R5cGUiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDE2KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikKYGBgCgojIyBEZW1vZ3JhcGhpYyBEeW5hbWljcyBvZiBXZXN0IE1lZGl0ZXJyYW5lYW4KCiMjIyBGaWd1cmUgNWE6IE5HUklQIGFuZCBHSVNQIGZvciBMR00gdG8gSG9sb2NlbmUKCmBgYHtyIExhdGUgUGxlaXN0b2NlbmUgaWNlIGNvcmVzLCBlY2hvPVQsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD01fQppY2Vjb3JlcyAlPiUgZHBseXI6OmZpbHRlcih5ZWFycy5CUDw9MzUwMDAgJiB5ZWFycy5CUD49ODAwMCkgJT4lIAogIGdncGxvdCgpICsgCiAgZ2VvbV9saW5lKGFlcyh4PXllYXJzLkJQLCB5PWQxOE8uR0lTUDIucHB0KSwgY29sb3I9J3JlZCcsIGx3ZD0uMiwgYWxwaGE9LjUpICsgCiAgZ2VvbV9saW5lKGFlcyh4PXllYXJzLkJQLCB5PWQxOE8uTkdSSVAyLnBwdCksIGNvbG9yPSdibHVlJywgbHdkPS4yLCBhbHBoYT0uNSkgKyAKICBnZW9tX3Ntb290aChhZXMoeD15ZWFycy5CUCwgeT1kMThPLkdJU1AyLnBwdCwgY29sb3I9J2dpc3AyJywgbHR5PSdnaXNwMicpLCBtZXRob2Q9J2xvZXNzJywgc3Bhbj0uMDcsIHNlPUZBTFNFLCBsd2QgPSAxKSArIAogIGdlb21fc21vb3RoKGFlcyh4PXllYXJzLkJQLCB5PWQxOE8uTkdSSVAyLnBwdCwgY29sb3I9J25ncmlwMicsIGx0eT0nbmdyaXAyJyksIG1ldGhvZD0nbG9lc3MnLCBzcGFuPS4wNywgc2U9RkFMU0UsIGx3ZCA9IDEpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwobmFtZT1OVUxMLCB2YWx1ZXMgPWMoJ2dpc3AyJz0ncmVkJywnbmdyaXAyJz0nYmx1ZScpLCBsYWJlbHMgPSBjKCdHSVNQMicsJ05HUklQMicpKSArIAogIHNjYWxlX2xpbmV0eXBlX21hbnVhbChuYW1lPU5VTEwsIHZhbHVlcyA9YygnZ2lzcDInPSdzb2xpZCcsJ25ncmlwMic9J3NvbGlkJyksIGxhYmVscyA9IGMoJ0dJU1AyJywnTkdSSVAyJykpICsgCiAgc2NhbGVfeF9yZXZlcnNlKCkgKyAKICAjc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcz1jKDE5MDAwLDE0MDAwLDEwMDAwKSwgbGFiZWxzID0gYygiMTkwMDAiLCIxNDAwMCIsIjEwMDAwIiksIHRyYW5zID0gInJldmVyc2UiKSArIAogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKDE5MDAwLDE0MDAwLDEwMDAwKSwgbHR5PSdkYXNoZWQnLCBsd2Q9MC4zKSArIAogIGxhYnMoeD0ieWVhcnMgY2FsIEJQIiwgCiAgICAgICB5PSJkZWx0YSBPMThcbmNvbGRlciA8PCDigJQgPj4gd2FybWVyIiwgCiAgICAgICBjb2xvcj0iQ29yZXMiLAogICAgICAgdGl0bGU9IlBhbGVvY2xpbWF0ZSBQcm94aWVzIGZyb20gR3JlZW5sYW5kIEljZSBDb3JlcyIpICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj1jKC45NSwuMTUpLCAKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSwgCiAgICAgICAgI2F4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLTUpLAogICAgICAgICNwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgI3Bsb3QubWFyZ2luID0gbWFyZ2luKGw9MzAsIHI9MjAsIHQ9MjAsIGI9MjApCiAgICAgICAgKQpgYGAKCgojIyMgRmlndXJlIDViOiBTdW1tZWQgUHJvYmFiaWxpdHkgRGlzdHJpYnV0aW9uIChTUEQpIG9mIFJhZGlvY2FyYm9uIERhdGVzIGluIHRoZSBXZXN0IE1lZGl0ZXJyYW5lYW4KCiMjIyMgQ2FsaWJyYXRlIGRhdGVzCgpgYGB7ciBjYWxpYnJhdGUgZGF0ZXMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89VCwgcmVzdWx0cz0iaGlkZSJ9CmMxNGRhdGVzJEJQLmNhbC5tZWRpYW4gPC0gYzE0ZGF0ZXMgJT4lIAogIHdpdGgoLiwgY2FsaWJyYXRlKHg9QzE0Lm1lYW4sIGVycm9ycz1DMTQuU0QsIGNhbEN1cnZlcyA9IGNhbGliLmN1cnZlLCBub3JtYWxpc2VkPVRSVUUsIGNhbE1hdHJpeD1GQUxTRSkpICU+JSAKICBtZWRDYWwoKQpgYGAKCgojIyMjIENhbGN1bGF0ZSBTUEQKCmBgYHtyIFNQRC1hbGwsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89VCwgcmVzdWx0cz0iaGlkZSJ9CmRhdGUuYmlucyA8LSBjMTRkYXRlcyAlPiUgCiAgZHBseXI6OmZpbHRlcihjYWxpYi5jdXJ2ZSAhPSAibm9ybWFsIikgJT4lICAKICB3aXRoKC4sIGJpblByZXAoc2l0ZSwgQzE0Lm1lYW4sIDEwMCkpCgptb2RlbC5hbGwgPC0gYzE0ZGF0ZXMgJT4lIAogIGRwbHlyOjpmaWx0ZXIoY2FsaWIuY3VydmUgIT0gIm5vcm1hbCIpICU+JSAgCiAgd2l0aCguLCBjYWxpYnJhdGUoeD1DMTQubWVhbiwgZXJyb3JzPUMxNC5TRCwgY2FsQ3VydmVzID0gY2FsaWIuY3VydmUsIG5vcm1hbGlzZWQ9VFJVRSwgY2FsTWF0cml4PUZBTFNFKSkgJT4lIAogIG1vZGVsVGVzdCguLCAKICAgICAgICAgICAgZXJyb3JzID0gYzE0ZGF0ZXMkQzE0LlNELCAKICAgICAgICAgICAgdGltZVJhbmdlID0gYygzODAwMCw1MDAwKSwgCiAgICAgICAgICAgIHJ1bm0gPSA1MDAsIAogICAgICAgICAgICBtb2RlbD0iZXhwb25lbnRpYWwiLCAKICAgICAgICAgICAgZGF0ZW5vcm1hbGlzZWQ9VFJVRSwgCiAgICAgICAgICAgIG5zaW0gPSAyMDAsIAogICAgICAgICAgICBuY29yZXMgPSBuY29yZXMsCiAgICAgICAgICAgIG1ldGhvZCA9ICdjYWxzYW1wbGUnLCAKICAgICAgICAgICAgYmlucyA9IGRhdGUuYmlucykKYGBgCgoKIyMjIyBHcmFwaCBTUEQKCmBgYHtyIFNQRC1hbGwgZ3JhcGgsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVQsIHJlc3VsdHM9ImhpZGUifQpwYXIobWFyPWMoNywxMCw3LDMpKQpwbG90KG1vZGVsLmFsbCwgeGxpbSA9IGMoMzUwMDAsODAwMCksIGNvbC5vYnMgPSAncmVkJywgbHdkLm9icyA9IDMsIGRyYXdheGVzID0gRikKYXhpcygxLCBjZXguYXhpcyA9IDEsIHBvcyA9IC0uMDAwNikKYXhpcygyLCBjZXguYXhpcyA9IDEsIHBvcyA9IDM1NTAwKQptdGV4dChzaWRlPTEsIGxpbmU9MywgInllYXJzIGNhbCBCUCIsIGNleD0xLjMpCm10ZXh0KHNpZGU9MiwgbGluZT00LCAic3VtbWVkIHByb2JhYmlsaXR5IiwgY2V4PTEuMykKdGl0bGUobWFpbj1wYXN0ZSgiV2VzdCBNZWRpdGVycmFuZWFuIExhdGUgUGxlaXN0b2NlbmUgQXNzZW1ibGFnZXMgKE4gPSAiLCBucm93KHN1YnNldChjMTRkYXRlcywgY2FsaWIuY3VydmUgIT0gIm5vcm1hbCIpKSwgIikiKSwgY2V4Lm1haW4gPSAxLjUpCmBgYAoKCgojIyMgRmlndXJlIDVjOiBTUERzIG9mIEFnZ3JlZ2F0ZWQgVGVjaG5vY29tcGxleGVzCgojIyMjIENsYXNzaWZ5IGFnZ3JlZ2F0ZWQgdGVjaG5vY29tcGxleGVzCgpgYGB7ciBjbGFzc2lmaXkgdGVjaG5vY29tcGxleGVzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVQsIHJlc3VsdHM9ImhpZGUifQpjMTRkYXRlcyA8LSBjMTRkYXRlcyAlPiUgCiAgbXV0YXRlKGluZHVzdHJ5Lmdyb3VwID0gCiAgICAgICAgICAgY2FzZV93aGVuKAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImF1cmlnIikgfiAiQXVyaWduYWNpYW4iLCAKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJnZHJhdiIpIH4gIkdyYXZldHRpYW4iLCAgCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAic29sdXQiKSB+ICJTb2x1dHJlYW4iLAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgIm1pZGRsZSBzb2x1dHJlYW4iKSB+ICJTb2x1dHJlYW4iLCAKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJzYWxwIikgfiAiU29sdXRyZWFuIiwgICAgICAgICAgICAgIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImVwaWciKSB+ICJNYWdkYWxlbmlhbiIsICAKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJlcGktZ3IiKSB+ICJNYWdkYWxlbmlhbiIsCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAiZXBwaWciKSB+ICJNYWdkYWxlbmlhbiIsCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAiZXBwZ3IiKSB+ICJNYWdkYWxlbmlhbiIsCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAiYXBpZyIpIH4gIk1hZ2RhbGVuaWFuIiwKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJtYWdkIikgfiAiTWFnZGFsZW5pYW4iLAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImJhZGVnIikgfiAiTWFnZGFsZW5pYW4iLAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImdyYXZldCIpIH4gIkdyYXZldHRpYW4iLCAgCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAiZ3JhdnQiKSB+ICJHcmF2ZXR0aWFuIiwgIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImF6aWwiKSB+ICJFcGlwYWxlb2xpdGhpYyIsIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgInJvbWFuZWxsIikgfiAiRXBpcGFsZW9saXRoaWMiLCAKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJlcGlwYWwiKSB+ICJFcGlwYWxlb2xpdGhpYyIsIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgIm1lc29sIikgfiAiTWVzb2xpdGhpYyIsIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgInNhdXZlIikgfiAiTWVzb2xpdGhpYyIsIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgInRhcmRlbiIpIH4gIk1lc29saXRoaWMiLCAKICAgICAgICAgICAgIHN0cl9kZXRlY3QodG9sb3dlcihpbmR1c3RyeSksICJtb250Y2wiKSB+ICJNZXNvbGl0aGljIiwgCiAgICAgICAgICAgICBzdHJfZGV0ZWN0KHRvbG93ZXIoaW5kdXN0cnkpLCAibW9udGFkIikgfiAiTWVzb2xpdGhpYyIsIAogICAgICAgICAgICAgc3RyX2RldGVjdCh0b2xvd2VyKGluZHVzdHJ5KSwgImNhc3RlbCIpIH4gIk1lc29saXRoaWMiCiAgICAgICAgICAgICApLCAKICAgICAgICAgaW5kdXN0cnkuZ3JvdXAgPSBmYWN0b3IoaW5kdXN0cnkuZ3JvdXAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJBdXJpZ25hY2lhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHcmF2ZXR0aWFuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNvbHV0cmVhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWdkYWxlbmlhbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFcGlwYWxlb2xpdGhpYyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNZXNvbGl0aGljIikpLAogICAgICAgICAuYWZ0ZXI9aW5kdXN0cnkpCmBgYAoKCiMjIyMgQ2FsY3VsYXRlIFNQRHMgb2YgYWdncmVnYXRlZCB0ZWNobm9jb21wbGV4ZXMKCmBgYHtyIFNQRC1pbmR1c3RyaWVzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVQsIHJlc3VsdHM9ImhpZGUifQpjMTRkYXRlcy5pbmR1c3RyeS5ncm91cCA8LSBjMTRkYXRlcyAlPiUgCiAgZHBseXI6OmZpbHRlcighaXMubmEoaW5kdXN0cnkuZ3JvdXApICYgY2FsaWIuY3VydmUgIT0gIm5vcm1hbCIpCgpjMTRkYXRlcy5pbmR1c3RyeS5ncm91cCA8LSBjMTRkYXRlcy5pbmR1c3RyeS5ncm91cFtvcmRlcihjMTRkYXRlcy5pbmR1c3RyeS5ncm91cCRpbmR1c3RyeS5ncm91cCksIF0KCmRhdGUuYmlucyA8LSAgYzE0ZGF0ZXMuaW5kdXN0cnkuZ3JvdXAgJT4lIAogIHdpdGgoLiwgYmluUHJlcChzaXRlLCBDMTQubWVhbiwgMTAwKSkKCnN0YWNrZWQuc3BkIDwtIGMxNGRhdGVzLmluZHVzdHJ5Lmdyb3VwICU+JSAKICB3aXRoKC4sIGNhbGlicmF0ZSh4PUMxNC5tZWFuLCBlcnJvcnM9QzE0LlNELCBjYWxDdXJ2ZXMgPSBjYWxpYi5jdXJ2ZSwgbm9ybWFsaXNlZD1UUlVFLCBjYWxNYXRyaXg9RkFMU0UpKSAlPiUgCiAgc3RhY2tzcGQodGltZVJhbmdlPWMoMzUwMDAsODAwMCksIAogICAgICAgICAgIGJpbnM9ZGF0ZS5iaW5zLAogICAgICAgICAgIGdyb3VwPWMxNGRhdGVzLmluZHVzdHJ5Lmdyb3VwJGluZHVzdHJ5Lmdyb3VwLCAKICAgICAgICAgICBydW5tID0gNTAwLCAKICAgICAgICAgICBkYXRlbm9ybWFsaXNlZD1UUlVFKQpgYGAKCgojIyMjIEdyYXBoIFNQRHMKCmBgYHtyIFNQRC1pbmR1c3RyaWVzIGdyYXBoLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NiwgZWNobz1UfQpwYXIobWFyPWMoNywxMCw3LDMpKQpvcHRpb25zKGRpZ2l0cyA9IDcpCnBsb3Qoc3RhY2tlZC5zcGQsIAogICAgIHhsaW0gPSBjKDM1MDAwLDgwMDApLCAKICAgICByZXNjYWxlID0gVCwgCiAgICAgc3Bkbm9ybWFsaXNlZCA9IEYsIAogICAgIHR5cGUgPSAibXVsdGlwYW5lbCIsIAogICAgIGx3ZC5vYnMgPSAuNSwgCiAgICAgcnVubSA9IE5BLCAKICAgICBjZXgubGFiID0gMS4zLCAKICAgICBjZXguYXhpcyA9IDEsIAogICAgIHlsYWIgPSAic3VtbWVkIHByb2JhYmlsaXR5XG4iLCAKICAgICB4bGFiID0gInllYXJzIGNhbCBCUCIsCiAgICAgeW1hcmdpbiA9IDEsIAogICAgIGdhcEZhY3RvciA9IC40LCAKICAgICBsZWdlbmQuYXJnPWxpc3QoInRvcGxlZnQiLCBidHkgPSAibiIsIGhvcml6ID0gVCwgY2V4ID0gMSkpCiNheGlzKDEsIGNleC5heGlzID0gMiwgcG9zID0gLS4wMDA2KQojYXhpcygyLCBjZXguYXhpcyA9IDIsIHBvcyA9IDM1NTAwKQojbXRleHQoc2lkZT0xLCBsaW5lPTUsICJ5ZWFycyBjYWwgQlAiLCBjZXg9Mi41KQojbXRleHQoc2lkZT0yLCBsaW5lPTYsICJzdW1tZWQgcHJvYmFiaWxpdHkiLCBjZXg9Mi41KQp0aXRsZShtYWluPXBhc3RlKCJXZXN0IE1lZGl0ZXJyYW5lYW4gTGF0ZSBQbGVpc3RvY2VuZSBUZWNobm9jb21wbGV4ZXMgKE4gPSAiLCBucm93KGMxNGRhdGVzLmluZHVzdHJ5Lmdyb3VwKSwgIikiKSwgY2V4Lm1haW4gPSAxLjUpCmBgYAo=